package com.niceloo.nl_photo_picker;

import android.Manifest;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.VisibleForTesting;

import java.io.File;
import java.io.IOException;

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry;
import top.kikt.imagescanner.ImageScanner;
import top.kikt.imagescanner.PermissionsUtils;
import top.kikt.imagescanner.RefreshObserver;
import top.kikt.imagescanner.ResultHandler;
import top.kikt.imagescanner.util.LogUtils;

/** NlPhotoPickerPlugin */
public class NlPhotoPickerPlugin implements MethodCallHandler {


  private static final String CHANNEL = "plugins.flutter.io/image_picker";

  private static final int SOURCE_CAMERA = 0;
  private static final int SOURCE_GALLERY = 1;

  private final PluginRegistry.Registrar registrar ;
  private final NLImagePickerDelegate delegate;

  private  RefreshObserver notifyChangeObserver = new RefreshObserver();
  private PermissionsUtils permissionsUtils = new PermissionsUtils();
  private ImageScanner scanner;
  /** Plugin registration. */
  public static void registerWith(PluginRegistry.Registrar registrar) {
    final MethodChannel channel = new MethodChannel(registrar.messenger(), "nl_photo_picker");

    final File externalFilesDirectory =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
           // registrar.activity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);

    final ExifDataCopier exifDataCopier = new ExifDataCopier();
    final ImageResizer imageResizer = new ImageResizer(externalFilesDirectory, exifDataCopier);

    final NLImagePickerDelegate delegate =
            new NLImagePickerDelegate(registrar.activity(), externalFilesDirectory, imageResizer);
    registrar.addActivityResultListener(delegate);
    registrar.addRequestPermissionsResultListener(delegate);

    final NlPhotoPickerPlugin instance = new NlPhotoPickerPlugin(registrar, delegate);
    channel.setMethodCallHandler(instance);
    /*registrar.addRequestPermissionsResultListener(new PluginRegistry.RequestPermissionsResultListener() {
      @Override
      public boolean onRequestPermissionsResult(int id, String[] permissions, int[] grantResults) {
        permissionsUtils.dealResult(id, permissions, grantResults);
        return false;
      }
    });
    permissionsUtils.setPermissionsListener(new PermissionsListener() {
      @Override
      public void onDenied(String[] deniedPermissions) {

      }

      @Override
      public void onGranted() {

      }
    });*/

  }
  @VisibleForTesting
  NlPhotoPickerPlugin(PluginRegistry.Registrar registrar, NLImagePickerDelegate delegate) {
    this.registrar = registrar;
    this.delegate = delegate;
    notifyChangeObserver.initWith(registrar);
    scanner = new ImageScanner(registrar);
  }
  @Override
  public void onMethodCall(MethodCall call,final Result rawResult) {
    MethodChannel.Result result = new MethodResultWrapper(rawResult);
    ResultHandler resultHandler = new ResultHandler(result);
    if (registrar.activity() == null) {
      result.error("no_activity", "image_picker plugin requires a foreground activity.", null);
      return;
    }
    if (call.method.equals("getPlatformVersion")) {
      result.success("Android " + android.os.Build.VERSION.RELEASE);
    } else if (call.method.equals("pickImage")) {
      int imageSource = call.argument("source");
      switch (imageSource) {
        case SOURCE_GALLERY:
          delegate.chooseImageFromGallery(call, result);
          break;
        case SOURCE_CAMERA:
          Log.i("---onMethodCall线程--",Thread.currentThread().getId()+"");
          delegate.takeImageWithCamera(call, result);
          break;
        default:
          throw new IllegalArgumentException("Invalid image source: " + imageSource);
      }
    } else if (call.method.equals("pickVideo")) {
      int imageSource = call.argument("source");
      switch (imageSource) {
        case SOURCE_GALLERY:
          delegate.chooseVideoFromGallery(call, result);
          break;
        case SOURCE_CAMERA:
          delegate.takeVideoWithCamera(call, result);
          break;
        default:
          throw new IllegalArgumentException("Invalid video source: " + imageSource);
      }
    }else if (call.method.equals("saveImage")) {


      try {
        delegate.saveImageToGallery(call, result);
      } catch (IOException e) {
        e.printStackTrace();
        throw new IllegalArgumentException(e);
      }


    } else if (call.method .equals("openSetting") ) {
      resultHandler.reply("");
      permissionsUtils.getAppDetailSettingIntent(registrar.activity());
    }else if (call.method .equals( "requestPermission")) {
      String[] permissions ={Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};
      delegate.requestpermissions(permissions,call, result);
    }else if(call.method .equals( "getGalleryNameList")){
      scanner.getPathListWithPathIds(call, result);
    }else if(call.method .equals( "getImageListWithPathId")){
      scanner.getImageListWithPathId(call, result);
    }else if(call.method .equals( "getAllImageList")){
      scanner.getAllImageList(call, result);
    }else if(call.method .equals( "getImageThumbListWithPathId")){
      scanner.getImageThumbListWithPathId(call, result);
    }else if(call.method .equals( "getThumbPath")){
      scanner.getImageThumb(call, result);
    }else if(call.method .equals( "getThumbBytesWithId")){
      scanner.getImageThumbData(call, result);
    }else if(call.method .equals( "createThumbWithPathId")){
      scanner.createThumbWithPathId(call, result);
    }else if(call.method .equals( "createThumbWithPathIdAndIndex")){
      scanner.createThumbWithPathIdAndIndex(call, result);
    }else if(call.method .equals( "getAssetTypeWithIds")){
      scanner.getAssetTypeWithIds(call, result);
    }else if(call.method .equals( "getDurationWithId")){
      scanner.getAssetDurationWithId(call, result);
    }else if(call.method .equals( "getSizeWithId")){
      scanner.getSizeWithId(call, result);
    }else if(call.method .equals( "releaseMemCache")){
      scanner.releaseMemCache(result);
    }else if(call.method .equals( "getAllVideo")){
      scanner.getAllVideo(result);
    }else if(call.method .equals( "getOnlyVideoWithPathId")){
      scanner.getOnlyVideoWithPathId(call, result);
    }else if(call.method .equals( "getAllImage")){
      scanner.getAllImage(result);
    }else if(call.method .equals( "getOnlyImageWithPathId")){
      scanner.getOnlyImageWithPathId(call, result);
    }else if(call.method .equals( "getTimeStampWithIds")){
      scanner.getTimeStampWithIds(call, result);
    }else if(call.method .equals( "assetExistsWithId")){
      scanner.checkAssetExists(call, result);
    }else if(call.method .equals( "log")){
      LogUtils.isLog = call.arguments();
    }else if(call.method .equals( "getGalleryIdList")){
      scanner.scanAndGetImageIdList(call, result);
    }else if(call.method .equals( "getVideoPathList")){
      scanner.getVideoPathIdList(call, result);
    }else if(call.method .equals( "getImagePathList")){
      scanner.getImagePathIdList(call, result);
    }else if(call.method .equals( "createAssetWithId")){
      scanner.createAssetWithId(call, result);
    }else {
      result.notImplemented();
    }
  }



  private static class MethodResultWrapper implements MethodChannel.Result {
    private MethodChannel.Result methodResult;
    private Handler handler;

    MethodResultWrapper(MethodChannel.Result result) {
      methodResult = result;
      handler = new Handler(Looper.getMainLooper());
    }

    @Override
    public void success(final Object result) {
      handler.post(
              new Runnable() {
                @Override
                public void run() {
                  methodResult.success(result);
                }
              });
    }

    @Override
    public void error(
            final String errorCode, final String errorMessage, final Object errorDetails) {
      handler.post(
              new Runnable() {
                @Override
                public void run() {
                  methodResult.error(errorCode, errorMessage, errorDetails);
                }
              });
    }

    @Override
    public void notImplemented() {
      handler.post(
              new Runnable() {
                @Override
                public void run() {
                  methodResult.notImplemented();
                }
              });
    }
  }
}
